package com.itheima.health.service.impl;

import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.SetMealDao;
import com.itheima.health.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据报表service
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private SetMealDao setMealDao;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 套餐预约情况统计
     *
     * @return }
     */
    @Override
    public Map<String, Object> getSetmealReport() {
        //1.查询所有的预约套餐id
        List<Integer> setmealIds = orderDao.findSetmealIds();
        //去重
        setmealIds = setmealIds.stream().distinct().collect(Collectors.toList());
        log.info("[所有预约套餐的id是]{}", setmealIds);

        //2.根据套餐id查询套餐名称
        List<String> setmealNames = setMealDao.findSetmealNamesByIds(setmealIds);
        log.info("[所有预约套餐的名称是]{}", setmealNames);
        //4.根据所有id查询 预约套餐的数量和名字存入map
        List<Map<String, String>> setmealCount = new ArrayList<>();
        for (Integer setmealId : setmealIds) {
            HashMap<String, String> map = new HashMap();
            //根据套餐id查询套餐名称
            String setmealName = setMealDao.findSetmealNameById(setmealId);
            //根据套餐id查询套餐预约数量
            String value = orderDao.findSetmealCountById(setmealId);

            map.put("name", setmealName);
            map.put("value", value);

            setmealCount.add(map);
        }

        //5.返回结果
        Map<String, Object> resultMap = new HashMap<>();
        setmealIds.forEach((setmealId) -> setMealDao.findSetmealNameById(setmealId));
        resultMap.put("setmealNames", setmealNames);
        resultMap.put("setmealCount", setmealCount);
        return resultMap;
    }

    @Override
    public Map<String, String> findExcelMap() {
        //1.新建一个map和用来存储返回数据
        Map<String, String> excelMap = new HashMap<>();
        //2.获得当前日期,并放入集合中
        //当前日期
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        excelMap.put("today", today);
        //3.到会员表查询今日新增会员数
        Integer countNewMember = memberDao.getCountNewMember(today);
        excelMap.put("countNewMember", countNewMember.toString());
        //4.查询本周新增会员数
        Integer countWeekNewMember = memberDao.getCountWeekNewMember();
        excelMap.put("countWeekNewMember", countWeekNewMember.toString());
        //5.查询本月新增会员数
        Integer countMonthNewMember = memberDao.getCountMonthNewMember();
        excelMap.put("countMonthNewMember", countMonthNewMember.toString());
        //6.查询总会员数
        Integer countTotalMember = memberDao.getCountTotalMember();
        excelMap.put("countTotalMember", countTotalMember.toString());
        //7.去预约表中查询今日预约数
        Integer countOrderNumber = orderDao.getCountOrderNumber(today);
        excelMap.put("countOrderNumber", countOrderNumber.toString());
        //8.查询今日到诊数
        Integer countVisitsNumber = orderDao.getCountVisitsNumber(today, "已到诊");
        excelMap.put("countVisitsNumber", countVisitsNumber.toString());
        //9.查询本周预约数
        Integer countWeekOrderNumber = orderDao.getCountWeekOrderNumber();
        excelMap.put("countWeekOrderNumber", countWeekOrderNumber.toString());
        //10.查询本周到诊数
        Integer countWeekVisitsNumber = orderDao.getCountWeekVisitsNumber("已到诊");
        excelMap.put("countWeekVisitsNumber", countWeekVisitsNumber.toString());
        //11.查询本月预约数
        Integer countMonthOrderNumber = orderDao.getCountMonthOrderNumber();
        excelMap.put("countMonthOrderNumber", countMonthOrderNumber.toString());
        //12.查询本月到诊数
        Integer countMonthVisitsNumber = orderDao.getCountMonthVisitsNumber("已到诊");
        excelMap.put("countMonthVisitsNumber", countMonthVisitsNumber.toString());
        //13.查询热门套餐信息
        List<Map<String, Object>> hotSetmeal = orderDao.getHotSetmeal();
        //14.查询总预约数
        Integer totalOrders = orderDao.getCount();
        BigDecimal bigDecimal = new BigDecimal(totalOrders + "");
        //取出第一条信息
        if (hotSetmeal.size() >= 1) {
            Map<String, Object> stringObjectMap1 = hotSetmeal.get(0);
            excelMap.put("hotSetmeal1", stringObjectMap1.get("name").toString());
            excelMap.put("number1", stringObjectMap1.get("number").toString());
            BigDecimal bigDecimal1 = new BigDecimal(stringObjectMap1.get("number").toString());
            excelMap.put("proportion1", bigDecimal1.divide(bigDecimal, 4, BigDecimal.ROUND_HALF_UP).toString());
        }
        if (hotSetmeal.size() >= 2) {
            Map<String, Object> stringObjectMap2 = hotSetmeal.get(1);
            excelMap.put("hotSetmeal2", stringObjectMap2.get("name").toString());
            excelMap.put("number2", stringObjectMap2.get("number").toString());
            BigDecimal bigDecimal2 = new BigDecimal(stringObjectMap2.get("number").toString());
            excelMap.put("proportion2", bigDecimal2.divide(bigDecimal, 4, BigDecimal.ROUND_HALF_UP).toString());
        }
        return excelMap;
    }

    @Override
    public Map getBusinessReportData() {
        String orderStatus = "已到诊";
        Map<String, Object> map = new HashMap<>();
        //当前时间(2022-8-3 )
        Date date = new Date();
        String time = String.format("%tF", date);//2022-8-3
        // todayVisitsNumber:今日到诊数
        map.put("todayVisitsNumber", orderDao.getCountVisitsNumber(time, orderStatus));
        // reportDate:报告日期
        map.put("reportDate", time);
        // todayNewMember:新增会员数
        map.put("todayNewMember", memberDao.getCountNewMember(time));
        // thisWeekVisitsNumber:本周到诊数
        map.put("thisWeekVisitsNumber", orderDao.getCountWeekVisitsNumber(orderStatus));
        // thisMonthNewMember：本月新增会员数。
        map.put("thisMonthNewMember", memberDao.getCountMonthNewMember());
        // thisWeekNewMember：本周新增会员数
        map.put("thisWeekNewMember", memberDao.getCountWeekNewMember());
        // totalMember"：会员总数。
        map.put("totalMember", memberDao.getCountTotalMember());
        // thisMonthOrderNumber：本月预约数
        map.put("thisMonthOrderNumber", orderDao.getCountMonthOrderNumber());
        // thisMonthVisitsNumber：本月到诊数
        map.put("thisMonthVisitsNumber", orderDao.getCountMonthVisitsNumber(orderStatus));
        // todayOrderNumber：今日预约数。
        map.put("todayOrderNumber", orderDao.getCountOrderNumber(time));
        // thisWeekOrderNumber：本周预约数
        map.put("thisWeekOrderNumber", orderDao.getCountWeekOrderNumber());
        // hotSetmeal:热点套餐（数组）
        List<Map<String, Object>> hotSetmeal = orderDao.getHotSetmeal2();//热点套餐

        BigDecimal count = new BigDecimal(orderDao.getCount());//预约套餐总数

        for (Map<String, Object> stringObjectMap : hotSetmeal) {
            Object number1 = stringObjectMap.get("setmeal_count");
            BigDecimal number = new BigDecimal(number1.toString());//当前套餐的预约数量。
            BigDecimal proportion = number.divide(count, 4, BigDecimal.ROUND_HALF_UP);//占比
            stringObjectMap.put("proportion", proportion);

        }
        //设置预约套餐
        map.put("hotSetmeal", hotSetmeal);
        return map;
    }

    @Override
    public Map<String, List> getMemberReport() {
        Map<String, List> reportData = new HashMap<>();
        ArrayList<String> months = new ArrayList<>();
        ArrayList<Integer> memberCount = new ArrayList<>();
        Calendar nowCalendar = Calendar.getInstance();
        months.add(nowCalendar.get(Calendar.YEAR) + "." + String.format("%02d", (nowCalendar.get(Calendar.MONTH) + 1)));//Calendar的月份 是从0开始的
//        Integer countTotalMembers = memberDao.getCountTotalMembers();//查询当月累计所有的会员数量

        //优化：先去redis中查询会员总数，Redis中没有的话，再去数据库中查询会员总数
        Integer countTotalMembers = (Integer) redisTemplate.opsForValue().get("countTotalMembers");
        if (countTotalMembers != null) {
            Integer countTodayNewMember = memberDao.getCountNewMember(nowCalendar.get(Calendar.YEAR) + "." + String.format("%02d", (nowCalendar.get(Calendar.MONTH) + 1)) + "." + nowCalendar.get(Calendar.DAY_OF_MONTH));
            countTotalMembers += countTodayNewMember;
            memberCount.add(countTotalMembers);
        } else {
            countTotalMembers = memberDao.getCountTotalMembers();
            memberCount.add(countTotalMembers);
            redisTemplate.opsForValue().set("countTotalMembers", countTotalMembers);
        }

        for (int i = -1; i > -12; i--) {
            nowCalendar.add(Calendar.MONTH, -1);//当前时间往前推11个月
            int year = nowCalendar.get(Calendar.YEAR);
            int month = nowCalendar.get(Calendar.MONTH) + 1;
            String formatmonth = String.format("%02d", month);//个位数月份前面补0
            String yearMonth = year + "." + formatmonth;
            months.add(yearMonth);

            //当月累计所有的会员数量 - 当月新增会员数量 = 上一月的累计会员数量
            month = month + 1;
            formatmonth = String.format("%02d", month);
            yearMonth = year + "." + formatmonth;

            Integer countMonthNewMember = memberDao.getCountMonthMember(yearMonth);
            countTotalMembers = countTotalMembers - countMonthNewMember;
            memberCount.add(countTotalMembers);

        }
        Collections.reverse(months);
        Collections.reverse(memberCount);

        reportData.put("months", months);
        reportData.put("memberCount", memberCount);


        return reportData;
    }
}
